interface NodeCmp<T> {
    int cmp(T d1, T d2);
}

interface MList<T> {
    public MList add(T data);
    public T find(T key, NodeCmp<T> cmpObj);
    public boolean next();
    public T value();
    public MList show();
}

class Node<T> {
    private T data;
    private Node<T> next;
    private Node<T> prev;

    private Node() {
        data = null;
        next = null;
        prev = null;
    }

    private Node(T data, Node<T> next, Node<T> prev) {
        this.data = data;
        this.next = next;
        this.prev = prev;
    }

    static public <T> MList<T> getList() {
        return new List<T>();
    }

    static public class List<T> implements MList<T> {
        private Node<T> head;
        private int len;
        private Node<T> it;

        public List() {
            head = new Node<T>();
            head.next = head;
            head.prev = head;
            len = 0;
            it = null;
        }

        public MList add(T data) {
            Node<T> newNode = new Node<T>(data, head, head.prev);
            head.prev.next = newNode;
            head.prev = newNode;
            len++;
            return this;
        }

        public T find(T key, NodeCmp<T> cmpObj) {
            for (Node<T> tail = head.next; tail != head; tail = tail.next) {
                if (cmpObj.cmp(key, tail.data) == 0)
                    return tail.data;
            }
            return null;
        }
        public boolean next() {
            if (it == null) {
                it = head.next;
            } else if (it.next == head) {
                it = null;
                return false;
            } else {
                it = it.next;
            }
            return true;
        }

        public T value() {
            if (it == null)
                return null;
            return it.data;
        }

        public MList show() {
            System.out.printf("[");
            for (Node<T> tail = head.next; tail != head; tail = tail.next) {
                System.out.print(tail.data);
                if (tail.next != head)
                    System.out.printf(", ");
            }
            System.out.printf("]\n");

            return this;
        }
    }
}

